package io.shuttle.mbe.api

import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.JSObject

////////////////////
// Events
////////////////////
/**
 * The `Browser.events` namespace contains common types used by APIs dispatching events to notify you when something interesting happens.
 */
interface Events {
    interface Event<Callback> {
        fun addListener(callback: Callback)

        // True if any event listeners are registered to the event.
        fun hasListener(callback: Callback): Boolean

        // True if any event listeners are registered to the event.
        fun hasListeners(): Boolean

        fun removeListener(callback: Callback)

        fun addRules(
            rules: List<Rule>,
            // @param {callback.rules}
            callback: Value1Function<List<Rule>>? = null
        )

        // @param ruleIdentifiers If an array is passed, only rules with identifiers contained in this array are returned.
        fun getRules(
            ruleIdentifiers: List<String>?,
            // // @param {callback.rules}
            callback: Value1Function<List<Rule>>? = null
        )

        // Unregisters currently registered rules.
        fun removeRules(
            ruleIdentifiers: List<String>?,
            callback: VoidFunction? = null
        )
    }

    data class UrlFilter(
        // Matches if the hostname of the URL (without protocol or port – see schemes and ports) contains the given string.
        var hostContains: String?,
        // Matches if the hostname of the URL is equal to a specified string.
        var hostEquals: String?,
        // Matches if the hostname of the URL starts with a specified string.
        var hostPrefix: String?,
        // Matches if the hostname of the URL ends with a specified string.
        var hostSuffix: String?,
        // Matches if the path segment of the URL contains a specified string.
        var pathContains: String?,
        // Matches if the path segment of the URL is equal to a specified string.
        var pathEquals: String?,
        // Matches if the path segment of the URL starts with a specified string.
        var pathPrefix: String?,
        // Matches if the path segment of the URL ends with a specified string.
        var pathSuffix: String?,
        // Matches if the query segment of the URL contains a specified string.
        var queryContains: String?,
        // Matches if the query segment of the URL is equal to a specified string.
        var queryEquals: String?,
        // Matches if the query segment of the URL starts with a specified string.
        var queryPrefix: String?,
        // Matches if the query segment of the URL ends with a specified string.
        var querySuffix: String?,
        // Matches if the URL (without fragment identifier) contains a specified string.
        // Port numbers are stripped from the URL if they match the default port number.
        var urlContains: String?,
        // Matches if the URL (without fragment identifier) is equal to a specified string.
        // Port numbers are stripped from the URL if they match the default port number.
        var urlEquals: String?,
        // Matches if the URL (without fragment identifier) matches a specified regular expression.
        // Port numbers are stripped from the URL if they match the default port number.
        var urlMatches: String?,
        // Matches if the URL without query segment and fragment identifier matches a specified regular expression.
        // Port numbers are stripped from the URL if they match the default port number.
        var originAndPathMatches: String?,
        // Matches if the URL (without fragment identifier) starts with a specified string.
        // Port numbers are stripped from the URL if they match the default port number.
        var urlPrefix: String?,
        // Matches if the URL (without fragment identifier) ends with a specified string.
        // Port numbers are stripped from the URL if they match the default port number.
        // Note that an implicit forward slash "/" is added after the host,
        // so "com/" matches https://example.com, but "com" does not.
        var urlSuffix: String?,
        // array of string. Matches if the scheme of the URL is equal to any of the schemes specified in the array.
        // Because schemes are always converted to lowercase,
        // this should always be given in lowercase or it will never match.
        var schemes: List<String>?,
        // array of (integer or (array of integer)).
        // An array which may contain integers and arrays of integers.
        // Integers are interpreted as port numbers, while arrays of integers are interpreted as port ranges.
        // Matches if the port of the URL matches any port number or is contained in any ranges.
        var ports: List<Int>?,
        /**
         * Matches if the host part of the URL is an IP address and is contained in any of the CIDR blocks specified in the array.
         * @since Chrome 123
         */
        var cidrBlocks: List<String>?
    )

    // Description of a declarative rule for handling events.
    data class Rule(
        // List of actions that are triggered if one of the conditions is fulfilled.
        var actions: List<Any>,
        // List of conditions that can trigger the actions.
        var conditions: List<JSObject>,
        // Optional identifier that allows referencing this rule.
        var id: String?,
        // Optional priority of this rule. Defaults to 100.
        var priority: Number?,
        // Tags can be used to annotate rules and perform operations on sets of rules.
        var tags: List<String>?
    )
}
